package com.RWM.activities;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.RWM.helpers.LatLonDistance;
import com.RWM.helpers.VenmoSDK;
import com.RWM.helpers.Zone;
import com.RWM.reference.Reference.RequestMethod;
import com.RWM.serverTools.Connect;
import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;

import android.app.ListActivity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class HomeActivity extends ListActivity implements OnClickListener{
	private Button btnIncZoneCnt, btnRefine, btnAddPickup, signout, facebookConnect;
	private Intent myIntent;
	private Location location;
	private LocationManager lm;
	private Connect connect, refineConnect;
	private String our_access_token;
	private List zones;
	RideWithMe context;
	AsyncFacebookRunner mAsyncRunner;
	
	//This is our app_id on facebook
		Facebook facebook = new Facebook("120238738108355");
		private SharedPreferences mPrefs;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		
		//context for accessing global data
		context = (RideWithMe) getApplicationContext();
		context.setFacebook(facebook);
		mAsyncRunner = new AsyncFacebookRunner(facebook);
		 mPrefs = getPreferences(MODE_PRIVATE);
	        String access_token = mPrefs.getString("access_token", null);
	     
	        long expires = mPrefs.getLong("access_expires", 0);
	        
	    	
			/*
	         * Get existing facebook access_token if any
	         */
	       
	        if(access_token != null) {
	            facebook.setAccessToken(access_token);
	        }
	        if(expires != 0) {
	            facebook.setAccessExpires(expires);
	        }
	
		lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
		
		myIntent = getIntent();
		Bundle extras = myIntent.getExtras();
		access_token = extras.getString("access_token");
		Log.v("test", "Got User ID " + access_token);
		
		// Remove driver that have been created beyond 2 hours ago. 
		Connect myConnect = new Connect("http://m.cip.gatech.edu/developer/imf/api/RWMSERVER/updatedriverlist/");
		try {
			myConnect.Execute(RequestMethod.GET);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//Receive and parse JSONArray of zone info from database
		connect = new Connect("http://m.cip.gatech.edu/developer/imf/api/RWMSERVER/home/");
		try {
			connect.Execute(RequestMethod.GET);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		  }
		
		JSONArray zoneInfo = null;
		try {
			zoneInfo = new JSONArray(connect.getResponse());
		}  catch (JSONException e) {
			Log.v("json", "Could not create JSONArray");
		}
		
		zones = new ArrayList<Zone>();
		JSONObject zone = null;
		for (int i = 0; i < zoneInfo.length(); i++) {
			try {
				zone = zoneInfo.getJSONObject(i);
				zones.add(new Zone(zone.getInt("pzoneID"),	zone.getInt("riderCount"),
						        zone.getString("address"), zone.getDouble("latitude"),
						        zone.getDouble("longitude")));
			} catch(JSONException e) {
				Log.v("json", "Could not create ArrayList from JSONArray");
			}
					
		}
		ArrayAdapter<String> arrAdapter = new ArrayAdapter<String>(this, R.layout.list, zones);

		/** 
		 * Normally we have a layout for the entire view. Here we have 2 layouts we want to combine.
		 * To do this, we use the LayoutInflator object to combine the two layouts. 
		 */
		LayoutInflater linflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View combinedLayouts = linflater.inflate(R.layout.home, this.getListView(), false);
		//combinedLayouts.getLayoutParams().height = 34;
		ListView lv = getListView();
		lv.setHeaderDividersEnabled(false);
		lv.addHeaderView(combinedLayouts);
		lv.setTextFilterEnabled(true);
		setListAdapter(arrAdapter);

		// List Item Listener
		lv.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				
				/* Prepare to go to the next window, but first we want to pass info to the next window. */
				myIntent = new Intent(HomeActivity.this,ZoneDetailActivity.class);
				int zoneid = ((Zone)zones.get((int)id)).getID();
				myIntent.putExtra("id", zoneid); // Pass in the zoneID so the next screen knows what parking zone you just clicked.
				myIntent.putExtra("txt", ((Zone)zones.get((int)id)).getAddress()); // Pass the parking zone name as well. 
				myIntent.putExtra("access_token", our_access_token);
				startActivity(myIntent);
			}
		});

		/* Button listener */
		btnIncZoneCnt = (Button)findViewById(R.id.btn_incZoneCnt);
		btnIncZoneCnt.setOnClickListener(this);
		btnRefine = (Button)findViewById(R.id.btn_refine);
		btnRefine.setOnClickListener(this);
		btnAddPickup = (Button)findViewById(R.id.btn_addPickUpArea);
		btnAddPickup.setOnClickListener(this);
		signout = (Button)findViewById(R.id.btn_signout);
		signout.setOnClickListener(this);
		facebookConnect = (Button)findViewById(R.id.btn_facebook);
		facebookConnect.setOnClickListener(this);

	}

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        facebook.authorizeCallback(requestCode, resultCode, data);
    }
	
	private void showMyAddress(Location location) {
		double latitude = location.getLatitude();
		double longitude = location.getLongitude();
		Geocoder myLocation = new Geocoder(getApplicationContext(), Locale.getDefault());   
		List<Address> myList;
		try {
			myList = myLocation.getFromLocation(latitude, longitude, 1);
			if(myList.size() == 1) {
				Toast.makeText(getApplicationContext(), myList.get(0).toString(), Toast.LENGTH_LONG).show();           
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	LocationListener locationListener = new LocationListener() {
		public void onLocationChanged(Location location) {
			
		}

		public void onProviderDisabled(String arg0) {
		
		}

		public void onProviderEnabled(String arg0) {
			// TODO Auto-generated method stub

		}

		public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
			// TODO Auto-generated method stub

		}
	};

	/**
	 * Not functional yet:
	 * When a user clicks this buttons, it will gather the users current latitude and longitude and send 
	 * this information to the server. 
	 */
	public void onClick(View v) {
		Intent intent;
		switch (v.getId()){
		
		case R.id.btn_facebook:
			
		      // if(!facebook.isSessionValid()) {
					//publish_stream required for wall posts
		            facebook.authorize(this, new String[] {"publish_stream"}, new DialogListener() {
		                public void onComplete(Bundle values) {
		                    SharedPreferences.Editor editor = mPrefs.edit();
		                    editor.putString("access_token", facebook.getAccessToken());
		                    editor.putLong("access_expires", facebook.getAccessExpires());
		                    editor.commit();
		                }
		    
		                public void onFacebookError(FacebookError error) {
		                	Log.v("test", error.getMessage());
		                }
		    
		                public void onError(DialogError e) {
		                	Log.v("test", "onError");
		                }
		    
		                public void onCancel() {
		                	Log.v("test", "onCancel");
		                }
		            });
		        //}
		       break;
		
		case R.id.btn_signout:
			
			mAsyncRunner.logout(this.getApplicationContext(), new RequestListener() {
				  public void onComplete(String response, Object state) {}
				  
				  public void onIOException(IOException e, Object state) {}
				  
				  public void onFileNotFoundException(FileNotFoundException e,
				        Object state) {}
				  
				  public void onMalformedURLException(MalformedURLException e,
				        Object state) {}
				  
				  public void onFacebookError(FacebookError e, Object state) {}
				});
			break;
		
		case R.id.btn_incZoneCnt:
			
			/* Use the LocationManager class to obtain GPS locations */
		    
			location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
			
			if(location != null) {
				Zone closestZone = null;
				double zoneLat=0, zoneLon=0, distanceToClosest=0, distance=0;
				for (int i=0; i < zones.size(); i++) {
					zoneLat = ((Zone)zones.get(i)).getLatitude();
				    zoneLon = ((Zone)zones.get(i)).getLongitude();
					distance = LatLonDistance.haversine(location.getLatitude(),
							location.getLongitude(), zoneLat, zoneLon);
					if(i==0 || distance < distanceToClosest) {
						distanceToClosest = distance;
						closestZone = ((Zone)zones.get(i));
					}
				}
				
				connect.setURL("http://m.cip.gatech.edu/developer/imf/api/RWMSERVER/pickupzone/");
				connect.AddParam("pzoneID", String.valueOf(closestZone.getID()));
				connect.AddParam("access_token", our_access_token);
				
				try {
					connect.Execute(RequestMethod.POST);
				} catch (Exception e) {
					Log.v("http", "Failed adding rider to pickup zone");
				}
			
			
			
				try {
					JSONObject confirm = new JSONObject(connect.getResponse());
					if(confirm.getInt("rowsAffected") == 1) {
						intent=getIntent();
					    intent.putExtra("access_token", our_access_token);
					    finish();
					    startActivity(intent);
					    Toast.makeText(HomeActivity.this, "You have been added" +
					    "to the zone at " + closestZone.getAddress(), Toast.LENGTH_LONG).show();
					    
					    //post to facebook wall
					    Log.v("test", facebook.getAccessToken());
					    Bundle parameters = new Bundle();
		                parameters.putString("message", "checked in to the pickup zone at " + closestZone.getAddress());
		                parameters.putString("description", "topic share");
		        	    facebook.request("me");
					    String response = facebook.request("me/feed", parameters, "POST");
					    Log.v("json", "got response: " + response);
						if (response == null || response.equals("") || response.equals("false")) {
								context.showToast("Blank response.");
						}
						else 
							context.showToast("Message posted to your facebook wall!");
						//end post to facebook wall
					} 
					else {
						Toast.makeText(HomeActivity.this, "Could not add you to the"
						+ " nearest location, please try again.", Toast.LENGTH_LONG).show();
					}
				} catch (JSONException e) {
					Log.v("json", "Could not retreive the rowsAffected field");
				}
				
				catch (Exception e) {
					context.showToast("Failed to post to wall!");
					e.printStackTrace();
					finish();
					}
			}
			
			else 
				Toast.makeText(HomeActivity.this, "Could not find your location",
				Toast.LENGTH_LONG).show();
			
			break;
		case R.id.btn_refine:
			
			refineConnect.setURL("http://m.cip.gatech.edu/developer/imf/api/RWMSERVER/home/");
		
			refineConnect.AddParam("long", "-84.435");
			refineConnect.AddParam("lat", "33.345");
			refineConnect.AddParam("radius",btnRefine.getText().toString());
			//long=-84.477439&lat=33.864848&radius=1
			try {
				refineConnect.Execute(RequestMethod.POST);
			} catch (Exception e) {
				Log.v("http", "Failed adding rider to pickup zone");
			}
			break;
		case R.id.btn_addPickUpArea:
			Intent myIntent = new Intent(HomeActivity.this, AddPickupAreaActivity.class);
			startActivity(myIntent);
			break;
		}

	}
	
	 public void onResume() {    
	        super.onResume();
	        context.getFacebook().extendAccessTokenIfNeeded(this, null);
	    }
	
}
